package com.guaoran.source.spring.framework.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author : 孤傲然
 * @Description :
 *  AOP 增强代理类
 * @date :2018/7/4 8:27
 */
public class AopProxy implements InvocationHandler {
    //要代理的类
    private Object target;
    //aop 增强信息
    private AopConfig aopConfig;
    public void setAopConfig(AopConfig aopConfig){
        this.aopConfig = aopConfig;
    }

    /**
     * 把原始对象传进来，返回代理的对象
     * @param instance
     * @return
     */
    public Object getAopProxy(Object instance){
        this.target = instance;
        Class<?> clazz = instance.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //  此处的method是*Service接口，
        //  通过接口中的方法信息，从target中获得出实现的类的方法，只有这样，才能从aop中获得出要增强的信息，

        Method m = this.target.getClass().getMethod(method.getName(),method.getParameterTypes());

        //此处应该是通过原始的方法 即没有被代理的方法进行判断，否则会拿不出来增强的对象信息
        //在原始方法调用之前需要增强处理的方法
        if(aopConfig.contains(m)){
            AopConfig.Aspect aspect = aopConfig.get(m);
            aspect.getPoints()[0].invoke(aspect.getAspect());
        }
        //反射调用原始方法
        Object o = method.invoke(this.target,args);
        //在原始方法调用之后需要增强处理的方法
        if(aopConfig.contains(m)){
            AopConfig.Aspect aspect = aopConfig.get(m);
            aspect.getPoints()[1].invoke(aspect.getAspect());
        }
        return o;
    }
}
